<?php
/**
 * Note: *
 * Date: 2019/11/28
 */
namespace App\Http\Controllers\Admin;

use App\Caches\GameServerCache;
use App\Caches\QuickSetCache;
use App\Caches\RoleAccessCache;
use App\Caches\RoleCache;
use App\Models\Game\Center\AppSource;
use App\Models\Game\Center\GoodsModifyTypes1;
use App\Models\Game\Center\GoodsModifyTypes2;
use App\Models\Game\Center\GoodsModifyTypes3;
use App\Models\Game\Center\Package;
use App\Models\Menu;
use App\Services\AuthService;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;

class IndexController extends BackendController
{
    /**
     * 引入后台模板
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function index()
    {
        return view('layouts.admin');
    }

    /**
     * 后台显示菜单
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function menu()
    {
        $menus = Menu::whereStatus(Menu::STATUS_ON)->orderByDesc('sort')->orderBy('id', 'ASC')->with('parentMenu')->get();
        $allAccess = [];
        foreach ($this->user->role as $roleId) {
            $allAccess = array_merge($allAccess, Arr::pluck(RoleCache::access($roleId), 'id', 'route'));
        }
        foreach ($menus as $k => $menu) {
            if ($menu->parentMenu && $menu->parentMenu->status === Menu::STATUS_OFF) {
                unset($menus[$k]);
            }
        }
        // 超管权限
        if (isset($allAccess['*'])) {
            return responseData($menus);
        }

        $authService = new AuthService();
        foreach ($menus as $k => $menu) {
            if (!$menu['access_id']) continue;
            $access = RoleAccessCache::first($menu['access_id']);
            //$routePrefix = substr($route, 0, strpos($route, '.') + 1);

            if (empty($access['route'])) continue;

            if (in_array($access['route'], $authService->getIgnorePermissions())) {
                continue;
            }
            // 模块权限 module.*
            //if (isset($allAccess[$routePrefix.'*'])) {
            //    continue;
            //}
            // 精准权限
            if (isset($allAccess[$access['route']])) {
                continue;
            }
            unset($menus[$k]);
        }
        return responseData($menus);
    }

    /**
     * 返回面板需要的数据
     * @return array|\Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function dashboard()
    {

        $data = Cache::remember('admin.index.dashboard', now()->addMinutes(10), function () {
            return DailyStat::ofField('day', now()->subDay()->format("Ymd"))
                ->selectRaw("IFNULL(register_num, 0) AS register, IFNULL(login_num, 0) AS login, IFNULL(draw_num, 0) AS draw_num, IFNULL(join_num, 0) AS join_num, IFNULL(invite_num, 0) AS invite_num, IFNULL(task, 0) AS task, IFNULL(red_packet, 0) AS red_packet")
                ->first();
        });

        return responseData($data);
    }

    public function dashCount(Request $request)
    {
        if ($request->timeRange){
            $timestampRange = array_map(function($v) {
                return date('Y-m-d', $v);
            }, $request->timeRange);
        }else{
            //近一周
            $timestampRange = [now()->subWeek()->toDateString(),now()->toDateString()];
        }
        $data = DailyStat::whereBetween('day',$timestampRange)->get();
        $rearr['data'] = $data;
        $rearr['total'] = count($rearr['data']);
        return json_encode($rearr);
    }

    /**
     * 通用 获取所有
     * @param string $modelName
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Resources\Json\AnonymousResourceCollection|\Illuminate\Http\Response
     */
    public function all(string $modelName)
    {
        $modelName = Str::studly($modelName);
        $class = "App\Models\\{$modelName}";
        if (!class_exists($class)) $class = "App\Models\Game\Center\\{$modelName}";
        if (!class_exists($class)) $class = "App\Models\Game\Main\\{$modelName}";
        if (!class_exists($class)) return responseException(__('api.no_result'));

        $model = new $class();
        if ($model instanceof Model) {
            $count = $model->count();
            if ($count > 500) $count = 500;

            // 物品变动项特殊处理多取一些
            if (in_array($class, [GoodsModifyTypes1::class, GoodsModifyTypes2::class, GoodsModifyTypes3::class])) {
                $count = 1000;
            }

            // 套餐只看状态正常的
            if ($model instanceof Package) $model = $model->whereStatus(1);
            if ($this->allowSources && $model instanceof AppSource) $model = $model->whereIn('id', $this->allowSources);
            return JsonResource::collection($model->limit($count)->get());
        }
        return responseException(__('api.failed'));
    }

    /**
     * 实时数据
     * @param Request $request
     * @param string $type
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function realTimeData(Request $request, string $type)
    {
        $data = [];
        switch ($type) {
            case 'waterline':
                $request->validate([
                    'ids' => 'required|array',
                ]);
                $data = [];
                foreach ($request->ids as $id) {
                    $data[$id] = GameServerCache::getStockWaterLine($id);
                }
                break;
            case 'prizePoolBulletHbPool':
                $request->validate([
                    'ids' => 'required|array',
                ]);
                foreach ($request->ids as $id) {
                    $data[$id] = GameServerCache::getPrizePoolBulletHbPool($id);
                }
                break;
            case 'sceneOnline':
                $request->validate([
                    'ids' => 'required|array',
                ]);
                foreach ($request->ids as $id) {
                    $data[$id] = GameServerCache::getSceneOnline($id);
                }
                break;
            default:
                break;
        }
        return responseData($data);
    }

    /**
     * 快速配置
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function quickSet(Request $request)
    {
        if ($request->isMethod('get')) {
            return responseData(QuickSetCache::all());
        }

        // 操作密码校验
        if (!verifyOperationPassword($request->password)) {
            return responseException(__('auth.failed'));
        }
        QuickSetCache::setAll($request->all());
        return responseMessage(__('web.success'));
    }

    /**
     * 根据文件名下载配置文件
     * @param string $name
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response|\Symfony\Component\HttpFoundation\BinaryFileResponse
     */
    public function downloadConfig(string $name)
    {
        $name = preg_replace('/[^a-zA-Z0-9\-_]+/', '', $name);
        $filepath = storage_path("excel/{$name}.xlsx");
        if (!file_exists($filepath)) {
            return responseException('配置文件不存在');
        }
        return response()->file($filepath);
    }
}
